<template>
  <div class="app-container">
    <el-row :gutter="24" class="novel-page">
      <!-- 左侧区域 -->
      <el-col :span="9" class="novel-page-left">
        <div class="left-panel">
          <!-- 角色列表 -->
          <div class="panel-section character-list">
            <div class="section-header">
              <div class="section-title">
                <el-icon><Avatar /></el-icon>
                角色列表
              </div>
              <div class="section-actions">
                <el-button type="primary" @click="handleAdd" size="small" plain>
                  <el-icon><Plus /></el-icon> 新增角色
                </el-button>
              </div>
            </div>
            <div class="section-body">
              <el-scrollbar height="calc(100% - 45px)" class="character-scrollbar">
                <el-table
                  v-loading="loading"
                  :data="characterList"
                  style="width: 100%"
                  @row-click="handleRowClick"
                  size="small"
                >
                  <el-table-column prop="name" label="角色名称" />
                  <el-table-column label="操作" width="120" align="center">
                    <template #default="scope">
                      <el-button
                        link
                        type="primary"
                        @click.stop="handleEdit(scope.row)"
                      >
                        编辑
                      </el-button>
                      <el-button
                        link
                        type="danger"
                        @click.stop="handleDelete(scope.row)"
                      >
                        删除
                      </el-button>
                    </template>
                  </el-table-column>
                </el-table>
              </el-scrollbar>
            </div>
          </div>

          <!-- AI对话区域 -->
          <div class="panel-section ai-chat-section">
            <div class="chat-container">
              <NovelAiChat
                ref="aiChatRef"
                class="novel-ai-chat"
                title="AI角色设定助手"
                placeholder="请输入您对角色的要求，例如：我想要一个性格开朗、勇敢的主角..."
                :loading="aiLoading"
                :enable-context="enableContext"
                :max-context-messages="10"
                @send="handleAiChat"
                @context-change="handleContextChange"
                @abort="handleAbortAI"
                :extra-buttons="[
                  {
                    text: '提取当前内容',
                    onClick: handleExtractCurrentAiContent
                  }
                ]"
              />
            </div>
          </div>
        </div>
      </el-col>

      <!-- 右侧内容编辑区域 -->
      <el-col :span="15" class="novel-page-right">
        <template v-if="currentProject">
          <!-- 项目信息卡片 -->
          <div class="content-header">
            <div class="project-info">
              <div class="project-title">
                <span class="label">项目：</span>
                <span class="value">{{ currentProject.title }}</span>
              </div>
              <el-tag type="info" effect="plain" class="project-tag">角色设定</el-tag>
            </div>
            <div class="action-buttons">
              <el-tooltip content="保存设定" placement="top">
                <el-button type="primary" :icon="Document" circle @click="handleSave" :loading="saveLoading" />
              </el-tooltip>
              <el-tooltip content="下一步" placement="top" v-if="canGoNext">
                <el-button type="success" :icon="Right" circle @click="handleNextStep" />
              </el-tooltip>
            </div>
          </div>

          <!-- 角色设定编辑 -->
          <div class="content-body">
            <el-scrollbar height="100%">
              <div class="form-container">
                <el-form
                  ref="characterFormRef"
                  :model="form"
                  :rules="rules"
                  label-width="100px"
                  class="character-form"
                >
                  <el-row :gutter="24">
                    <el-col :span="8">
                      <el-form-item label="角色名称" prop="name">
                        <el-input v-model="form.name" placeholder="请输入角色名称" />
                      </el-form-item>
                    </el-col>
                    <el-col :span="8">
                      <el-form-item label="性别" prop="gender">
                        <el-select v-model="form.gender" placeholder="请选择性别" style="width: 100%">
                          <el-option label="男" value="male" />
                          <el-option label="女" value="female" />
                          <el-option label="其他" value="other" />
                        </el-select>
                      </el-form-item>
                    </el-col>
                    <el-col :span="8">
                      <el-form-item label="年龄" prop="age">
                        <el-input-number v-model="form.age" :min="1" :max="150" style="width: 100%" />
                      </el-form-item>
                    </el-col>
                  </el-row>

                  <el-form-item label="角色类型" prop="roleType">
                    <el-select v-model="form.roleType" placeholder="请选择角色类型">
                      <el-option label="主角" value="protagonist" />
                      <el-option label="配角" value="supporting" />
                      <el-option label="反派" value="antagonist" />
                      <el-option label="NPC" value="npc" />
                    </el-select>
                  </el-form-item>

                  <el-form-item label="性格特点" prop="personality">
                    <el-input
                      v-model="form.personality"
                      type="textarea"
                      :rows="4"
                      placeholder="请输入性格特点"
                    />
                  </el-form-item>

                  <el-form-item label="背景故事" prop="background">
                    <el-input
                      v-model="form.background"
                      type="textarea"
                      :rows="8"
                      placeholder="请输入背景故事"
                    />
                  </el-form-item>
                </el-form>
              </div>
            </el-scrollbar>
          </div>
        </template>
        <el-empty v-else description="请先选择或创建一个小说项目" />
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { listCharacter, getCharacter, addCharacter, updateCharacter, deleteCharacter } from "@/api/novel/character"
import { getProject } from '@/api/novel/project'
import NovelAiChat from '@/components/NovelAiChat/index.vue'
import { useAIStream, PlatformType, AIModelType } from "@/components/Hook/useStreamFetch"
import { Document, Right, Avatar, Plus } from '@element-plus/icons-vue'
import{ getWorldSettingByProject } from'@/api/novel/worldSetting'

const route = useRoute()
const router = useRouter()

// 项目数据
const currentProject = ref(null)
const loading = ref(false)
const aiLoading = ref(false)
const saveLoading = ref(false)
const characterList = ref([])
const aiChatRef = ref(null)

// 世界观设定数据
const worldSetting = ref(null)

// 创建AI对话hook - 使用统一API
const aiChatHook = useAIStream({
  platform: PlatformType.VOLCANO,         // 使用火山平台
  authToken: '02419daf-d6b6-4d07-bdf7-385f483b5bf7',
  model: AIModelType.DEEPSEEK,            // 使用DEEPSEEK模型
  enableContext: true,                    // 启用上下文
  maxContextMessages: 10,                 // 最大上下文消息数
  debug: false                            // 是否开启调试模式
})

// 解构hook返回值
const {
  data: summaryData,
  isLoading: isSummaryLoading,
  lastMessage,
  chat: startAiChat
} = aiChatHook

// 表单参数
const form = ref({
  id: undefined,
  projectId: undefined,
  name: '',
  gender: '',
  age: 18,
  roleType: '',
  personality: '',
  background: ''
})

const rules = ref({
  name: [
    { required: true, message: '角色名称不能为空', trigger: 'blur' }
  ],
  gender: [
    { required: true, message: '请选择性别', trigger: 'change' }
  ],
  age: [
    { required: true, message: '请输入年龄', trigger: 'blur' }
  ],
  roleType: [
    { required: true, message: '请选择角色类型', trigger: 'change' }
  ],
  personality: [
    { required: true, message: '请输入性格特点', trigger: 'blur' }
  ],
  background: [
    { required: true, message: '请输入背景故事', trigger: 'blur' }
  ]
})

// 表单引用
const characterFormRef = ref(null)

// 计算属性
const canGoNext = computed(() => {
  return currentProject.value && characterList.value.length > 0
})

// 上下文控制状态
const enableContext = ref(true)

// 获取项目信息
const getProjectInfo = async () => {
  const projectId = route.query.projectId
  if (!projectId) {
    ElMessage.warning('请先选择小说项目')
    router.push('/novel/project')
    return
  }

  try {
    const response = await getProject(projectId.toString())
    currentProject.value = response.data
    form.value.projectId = projectId.toString()
    getCharacterList()

    // 获取世界观设定信息
    getWorldSettingInfo()
  } catch (error) {
    console.error('获取项目信息失败:', error)
    ElMessage.error('获取项目信息失败')
  }
}

// 获取世界观设定
const getWorldSettingInfo = async () => {
  if (!currentProject.value || !currentProject.value.id) {
    return
  }

  try {
    // 导入世界观设定API

    const response = await getWorldSettingByProject(currentProject.value.id.toString())

    if (response && response.data) {
      worldSetting.value = response.data

      console.log('已加载世界观设定:', worldSetting.value.name)

      // 将世界观设定作为上下文添加到AI对话中
      if (aiChatRef.value) {
        aiChatRef.value.addAiResponse({
          role: "system",
          content: `当前项目世界观设定：【${worldSetting.value.name}】\n\n${worldSetting.value.content}\n\n请基于这个世界观来创建角色设定。`
        })
      }
    } else {
      console.log('未找到世界观设定，将创建空白角色')
    }
  } catch (error) {
    console.error('获取世界观设定失败:', error)
  }
}

// 获取角色列表
const getCharacterList = async () => {
  loading.value = true
  try {
    const response = await listCharacter({
      projectId: currentProject.value.id.toString()
    })
    characterList.value = response.rows || []
  } catch (error) {
    console.error('获取角色列表失败:', error)
    ElMessage.error('获取角色列表失败')
  } finally {
    loading.value = false
  }
}

// 处理新增角色
const handleAdd = () => {
  form.value = {
    id: undefined,
    projectId: currentProject.value.id.toString(),
    name: '',
    gender: '',
    age: 18,
    roleType: '',
    personality: '',
    background: ''
  }
}

// 处理编辑角色
const handleEdit = async (row) => {
  try {
    const response = await getCharacter(row.id)
    form.value = {
      id: response.data.id.toString(),
      projectId: response.data.projectId.toString(),
      name: response.data.name,
      gender: response.data.gender,
      age: response.data.age,
      roleType: response.data.roleType,
      personality: response.data.personality,
      background: response.data.background
    }
  } catch (error) {
    console.error('获取角色详情失败:', error)
    ElMessage.error('获取角色详情失败')
  }
}

// 处理删除角色
const handleDelete = async (row) => {
  try {
    await ElMessageBox.confirm('确认要删除该角色吗？', '提示', {
      type: 'warning'
    })
    await deleteCharacter(row.id)
    ElMessage.success('删除成功')
    getCharacterList()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除角色失败:', error)
      ElMessage.error('删除角色失败')
    }
  }
}

// 处理行点击
const handleRowClick = (row) => {
  handleEdit(row)
}

// 处理保存
const handleSave = async () => {
  if (!characterFormRef.value) return

  try {
    await characterFormRef.value.validate()
    saveLoading.value = true

    const submitData = {
      ...form.value,
      id: form.value.id ? String(form.value.id) : undefined,
      projectId: form.value.projectId ? String(form.value.projectId) : undefined
    }

    if (form.value.id) {
      await updateCharacter(submitData)
      ElMessage.success('修改成功')
    } else {
      await addCharacter(submitData)
      ElMessage.success('保存成功')
    }
    getCharacterList()
  } catch (error) {
    if (error?.message) {
      ElMessage.error(error.message)
    } else {
      console.error('保存失败:', error)
      ElMessage.error('保存失败')
    }
  } finally {
    saveLoading.value = false
  }
}

// 处理下一步
const handleNextStep = () => {
  router.push({
    path: '/novel/mainPlot',
    query: { projectId: currentProject.value.id }
  })
}

// 处理上下文开关变化
const handleContextChange = (value) => {
  if (!value) {
    ElMessageBox.confirm(
      '禁用上下文后，AI将无法看到之前的对话历史。确定要禁用吗？',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    ).then(() => {
      aiChatRef.value?.clearHistory()
      enableContext.value = false
      ElMessage.success('已禁用上下文，对话历史已清空')
    }).catch(() => {
      enableContext.value = true
    })
  } else {
    enableContext.value = true
    ElMessage.success('已启用上下文，AI可以看到之前的对话历史')
  }
}

// 处理AI返回的消息
const parseAiResponse = (content: string, isRealtime = false) => {
  if (!content) return

  try {
    const lines = content.split('\n')
    const data = {}
    let currentKey = ''
    let currentValue = ''

    lines.forEach(line => {
      const trimmedLine = line.trim()

      if (trimmedLine.startsWith('1. 角色名称')) {
        currentKey = 'name'
        currentValue = ''
      } else if (trimmedLine.startsWith('2. 性别')) {
        if (currentKey && currentValue) {
          data[currentKey] = currentValue.trim()
        }
        currentKey = 'gender'
        currentValue = ''
      } else if (trimmedLine.startsWith('3. 年龄')) {
        if (currentKey && currentValue) {
          data[currentKey] = currentValue.trim()
        }
        currentKey = 'age'
        currentValue = ''
      } else if (trimmedLine.startsWith('4. 角色类型')) {
        if (currentKey && currentValue) {
          data[currentKey] = currentValue.trim()
        }
        currentKey = 'roleType'
        currentValue = ''
      } else if (trimmedLine.startsWith('5. 性格特点')) {
        if (currentKey && currentValue) {
          data[currentKey] = currentValue.trim()
        }
        currentKey = 'personality'
        currentValue = ''
      } else if (trimmedLine.startsWith('6. 背景故事')) {
        if (currentKey && currentValue) {
          data[currentKey] = currentValue.trim()
        }
        currentKey = 'background'
        currentValue = ''
      } else if (currentKey && trimmedLine) {
        // 提取方括号中的内容
        if (trimmedLine.startsWith('[') && trimmedLine.endsWith(']')) {
          // 如果整行都是方括号包裹的内容
          const content = trimmedLine.substring(1, trimmedLine.length - 1).trim()
          currentValue += content
        } else if (trimmedLine.includes('[') && trimmedLine.includes(']')) {
          // 如果方括号在行中间
          const match = trimmedLine.match(/\[(.*?)\]/)
          if (match && match[1]) {
            currentValue += match[1].trim()
          }
        } else if (!trimmedLine.startsWith('[') && !trimmedLine.startsWith(']')) {
          // 常规行内容
          currentValue += ' ' + trimmedLine
        }
      }
    })

    // 处理最后一个键值对
    if (currentKey && currentValue) {
      data[currentKey] = currentValue.trim()
    }

    // 特殊处理age字段
    if (data.age) {
      // 提取数字
      const ageMatch = data.age.match(/\d+/)
      if (ageMatch) {
        data.age = parseInt(ageMatch[0])
      }
    }

    // 特殊处理gender字段
    if (data.gender) {
      if (data.gender.includes('男')) {
        data.gender = 'male'
      } else if (data.gender.includes('女')) {
        data.gender = 'female'
      } else {
        data.gender = 'other'
      }
    }

    // 特殊处理roleType字段
    if (data.roleType) {
      if (data.roleType.includes('主角') || data.roleType.includes('主人公')) {
        data.roleType = 'protagonist'
      } else if (data.roleType.includes('配角')) {
        data.roleType = 'supporting'
      } else if (data.roleType.includes('反派')) {
        data.roleType = 'antagonist'
      } else {
        data.roleType = 'npc'
      }
    }

    if (isRealtime) {
      console.log('实时解析数据:', data)
    } else {
      console.log('最终解析数据:', data)
    }

    if (Object.keys(data).length > 0) {
      // 智能合并数据到表单
      const updatedForm = { ...form.value };

      // 只更新已有值，或者在实时模式下的完整字段
      Object.keys(data).forEach(key => {
        // 实时模式下，只更新非空值或明显完整的字段
        if (isRealtime) {
          // 姓名、性别等短字段即使在实时模式下也可以直接更新
          if (key === 'name' || key === 'gender' || key === 'age' || key === 'roleType') {
            if (data[key]) {
              updatedForm[key] = data[key];
            }
          }
          // 对于长文本字段，不立即更新，除非超过一定长度
          else if (key === 'personality' || key === 'background') {
            // 长度超过20个字符才认为内容可信
            if (data[key] && data[key].length > 20) {
              updatedForm[key] = data[key];
            }
          }
        }
        // 非实时模式(最终解析)，直接更新所有字段
        else {
          if (data[key]) {
            updatedForm[key] = data[key];
          }
        }
      });

      form.value = updatedForm;
    }
  } catch (error) {
    console.error('解析AI返回内容失败:', error)
  }
}

// 记录上一次解析的文本长度，用于增量解析
let lastParsedLength = 0;

// 监听AI响应数据，进行实时解析和显示
watch(summaryData, (newVal) => {
  if (newVal) {
    // 更新AI对话内容 - 流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, content: newVal })

    // 实时解析 - 只处理新增的内容
    if (newVal.length > lastParsedLength) {
      console.log("实时解析中..., 新增字符数:", newVal.length - lastParsedLength);
      parseAiResponse(newVal, true); // 传入true表示是实时解析
      lastParsedLength = newVal.length;
    }
  }
})

// 当最后一条消息完成时进行一次完整解析到表单
watch(lastMessage, (newVal) => {
  if (newVal && !isSummaryLoading.value) {
    // 加载完成时进行最终解析
    console.log("解析完整回复:", newVal);
    // 重置解析长度
    lastParsedLength = 0;
    // 进行一次完整解析
    parseAiResponse(newVal, false);
  }
})

// 监听AI加载状态
watch(isSummaryLoading, (newVal) => {
  aiLoading.value = newVal
  if (!newVal) {
    // 结束流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, end: true })
  }
})

// 处理AI对话
const handleAiChat = async (data) => {
  try {
    const { message, context } = data

    // 构建包含世界观设定的消息
    let userPrompt = message;
    
    // 系统提示词
    const systemPrompt = `你是一个小说助手，请根据用户的要求以及世界观设定为用户创建角色。以下是本小说的世界观设定：\n${worldSetting.value?.content || '暂无世界观设定'}\n\n请按照以下格式输出：\n\n1. 角色名称\n[角色名称]\n\n2. 性别\n[性别]\n\n3. 年龄\n[年龄]\n\n4. 角色类型\n[角色类型]\n\n5. 性格特点\n[详细描述性格特点]\n\n6. 背景故事\n[详细描述背景故事]`

    // 开始流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, start: true })

    console.log("开始AI请求:", {
      userPrompt: userPrompt.substring(0, 50) + "...",
      systemPrompt: systemPrompt.substring(0, 50) + "...",
    });

    // 使用与worldSetting组件相同的方式调用AI聊天
    await startAiChat(userPrompt, systemPrompt);

  } catch (error) {
    console.error('AI生成失败:', error)
    ElMessage.error('AI生成失败，请重试: ' + (error.message || error))
    // 结束流式显示
    if (aiChatRef.value) {
      aiChatRef.value.addAiResponse({ isStreaming: true, end: true })
    }
  } finally {
    aiLoading.value = false
  }
}

// 从当前AI回复中提取内容到表单
const handleExtractCurrentAiContent = (content) => {
  if (!content) {
    ElMessage.warning('没有找到AI生成的内容')
    return
  }

  handleManualAiContent(content)
}

// 手动处理AI输出内容填充表单
const handleManualAiContent = (content) => {
  try {
    const lines = content.split('\n')
    const data = {}
    let currentKey = ''
    let currentValue = ''

    lines.forEach(line => {
      const trimmedLine = line.trim()

      if (trimmedLine.startsWith('1. 角色名称')) {
        currentKey = 'name'
        currentValue = ''
      } else if (trimmedLine.startsWith('2. 性别')) {
        if (currentKey && currentValue) {
          data[currentKey] = currentValue.trim()
        }
        currentKey = 'gender'
        currentValue = ''
      } else if (trimmedLine.startsWith('3. 年龄')) {
        if (currentKey && currentValue) {
          data[currentKey] = currentValue.trim()
        }
        currentKey = 'age'
        currentValue = ''
      } else if (trimmedLine.startsWith('4. 角色类型')) {
        if (currentKey && currentValue) {
          data[currentKey] = currentValue.trim()
        }
        currentKey = 'roleType'
        currentValue = ''
      } else if (trimmedLine.startsWith('5. 性格特点')) {
        if (currentKey && currentValue) {
          data[currentKey] = currentValue.trim()
        }
        currentKey = 'personality'
        currentValue = ''
      } else if (trimmedLine.startsWith('6. 背景故事')) {
        if (currentKey && currentValue) {
          data[currentKey] = currentValue.trim()
        }
        currentKey = 'background'
        currentValue = ''
      } else if (currentKey && trimmedLine) {
        // 提取方括号中的内容
        if (trimmedLine.startsWith('[') && trimmedLine.endsWith(']')) {
          // 如果整行都是方括号包裹的内容
          const content = trimmedLine.substring(1, trimmedLine.length - 1).trim()
          currentValue += content
        } else if (trimmedLine.includes('[') && trimmedLine.includes(']')) {
          // 如果方括号在行中间
          const match = trimmedLine.match(/\[(.*?)\]/)
          if (match && match[1]) {
            currentValue += match[1].trim()
          }
        } else if (!trimmedLine.startsWith('[') && !trimmedLine.startsWith(']')) {
          // 常规行内容
          currentValue += ' ' + trimmedLine
        }
      }
    })

    // 处理最后一个键值对
    if (currentKey && currentValue) {
      data[currentKey] = currentValue.trim()
    }

    // 特殊处理age字段
    if (data.age) {
      // 提取数字
      const ageMatch = data.age.match(/\d+/)
      if (ageMatch) {
        data.age = parseInt(ageMatch[0])
      }
    }

    // 特殊处理gender字段
    if (data.gender) {
      if (data.gender.includes('男')) {
        data.gender = 'male'
      } else if (data.gender.includes('女')) {
        data.gender = 'female'
      } else {
        data.gender = 'other'
      }
    }

    // 特殊处理roleType字段
    if (data.roleType) {
      if (data.roleType.includes('主角') || data.roleType.includes('主人公')) {
        data.roleType = 'protagonist'
      } else if (data.roleType.includes('配角')) {
        data.roleType = 'supporting'
      } else if (data.roleType.includes('反派')) {
        data.roleType = 'antagonist'
      } else {
        data.roleType = 'npc'
      }
    }

    console.log('手动解析的数据:', data)

    if (Object.keys(data).length > 0) {
      form.value = {
        ...form.value,
        ...data
      }
      ElMessage.success('AI内容已成功填充到表单中')
    }
  } catch (error) {
    console.error('解析AI返回内容失败:', error)
    ElMessage.error('解析AI内容失败，请检查格式')
  }
}

// 处理终止AI对话
const handleAbortAI = () => {
  aiLoading.value = false
  // 结束流式显示
  if (aiChatRef.value) {
    aiChatRef.value.addAiResponse({ isStreaming: true, end: true })
  }
}

onMounted(() => {
  getProjectInfo()

  // 处理用户当前消息中的AI内容
  if (route.query.aiContent) {
    handleManualAiContent(route.query.aiContent)
  }
})
</script>

<style lang="scss" scoped>
.novel-page {
  height: calc(100vh - 110px);
  display: flex;

  .novel-page-left,
  .novel-page-right {
    height: 100%;
    display: flex;
    flex-direction: column;
  }

  .novel-page-left {
    .left-panel {
      height: 100%;
      display: flex;
      flex-direction: column;
      background: white;
      border-radius: 8px;
      border: 1px solid #ebeef5;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
      overflow: hidden;

      .panel-section {
        &.character-list {
          height: 300px;
          border-bottom: 1px solid #ebeef5;
          display: flex;
          flex-direction: column;

          .section-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px 16px;
            border-bottom: 1px solid #ebeef5;

            .section-title {
              display: flex;
              align-items: center;
              gap: 8px;
              font-size: 14px;
              font-weight: 500;
              color: #303133;
            }

            .section-actions {
              display: flex;
              gap: 8px;
            }
          }

          .section-body {
            flex: 1;
            overflow: hidden;
          }
        }

        &.ai-chat-section {
          flex: 1;
          display: flex;
          flex-direction: column;
          overflow: hidden;

          .chat-container {
            height: 100%;
            overflow: hidden;
            display: flex;
            flex-direction: column;

            :deep(.novel-ai-chat) {
              height: 100%;
              overflow: hidden;
              display: flex;
              flex-direction: column;

              .chat-messages {
                flex: 1;
                overflow: auto;
                padding: 16px;
              }
            }
          }
        }
      }
    }
  }

  .novel-page-right {
    .content-header {
      padding: 16px 24px;
      background: linear-gradient(90deg, #f9fafc, #f1f5fa);
      border-radius: 12px;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
      margin-bottom: 20px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      border: 1px solid rgba(214, 222, 235, 0.6);

      .project-info {
        display: flex;
        align-items: center;
        gap: 14px;

        .project-title {
          font-size: 16px;

          .label {
            color: #606266;
            font-weight: 500;
          }

          .value {
            font-weight: 600;
            color: #2c3e50;
          }
        }

        .project-tag {
          font-size: 13px;
        }
      }

      .action-buttons {
        display: flex;
        gap: 12px;
      }
    }

    .content-body {
      flex: 1;
      background: white;
      border-radius: 12px;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
      border: 1px solid rgba(214, 222, 235, 0.6);
      overflow: hidden;

      .form-container {
        padding: 24px;

        .character-form {
          :deep(.el-form-item__label) {
            font-weight: 500;
            color: #2c3e50;
          }

          :deep(.el-input__wrapper) {
            box-shadow: 0 0 0 1px #dcdfe6 inset;
            border-radius: 8px;
            transition: all 0.3s;

            &:hover, &:focus-within {
              box-shadow: 0 0 0 1px #409eff inset;
            }
          }
        }
      }
    }
  }
}
</style>

